#include "GnSystemPCH.h"
#include "GnLog.h"


using namespace log4cplus;

GnLogger* GnLogger::msSingletone = NULL;
GnCriticalSection GnLogger::msCriticalSection;
GnStaticDeclareFlagsInit(GnLogger, guchar);
const gtuint gMaxMessageLength = 256;
GnLogger::GnLogger(void) : mLogModule(NULL), mLoadLogSystem(false)
{
}

GnLogger::~GnLogger(void)
{
	if( mLogModule )
		FreeLibrary(mLogModule);
}

void GnLogger::EBMStartup()
{
	if( msSingletone == NULL)
		msSingletone = new GnLogger();

	msSingletone->Init();

}
void GnLogger::EBMShutdown()
{
	if( msSingletone )
		delete msSingletone;
}

GnLogger* GnLogger::GetInstance()
{
	return msSingletone;
}

bool GnLogger::UseUserSystemLog(bool useLog)
{
	if( !msSingletone )
		return false;

	if( useLog )
	{
		if( msSingletone->mLogModule )
			return true;

		if( !msSingletone->mLogModule )
		{
#if defined(GNDEBUG)
			msSingletone->mLogModule = LoadLibrary( GnText("log4cplusD.dll") );
#elif defined(GNLOG)
			msSingletone->mLogModule = LoadLibrary( GnText("log4cplusL.dll") );
#elif defined(GNRELEASE)
			msSingletone->mLogModule = LoadLibrary( GnText("log4cplusR.dll") );
#endif // #if defined(GNDEBUG)
		}
		if( !msSingletone->mLogModule )
		{
			GnOutputDebugString("Load Falied log4cplus-dll");
			return false;
		}

		msSingletone->mAppenOutputDebug = (AppenOutputDebugFunc)
			GetProcAddress( msSingletone->mLogModule, "AppendLogerOutputDebug" );
		msSingletone->mAppendFile = (AppendFileFunc)
			GetProcAddress( msSingletone->mLogModule, "AppendLogerFile" );
		
		msSingletone->mWriteFromLoggerLog = (WriteFromLoggerLogFunc)
			GetProcAddress( msSingletone->mLogModule, "WriteFromLoggerLog" );
		msSingletone->mWriteLog = (WriteLogFunc)
			GetProcAddress( msSingletone->mLogModule, "WriteLog" );

		msSingletone->mLoadLogSystem = true;

	}
	return true;
}

void GnLogger::Init()
{
#if defined(GNDEBUG) || defined(GNLOG)
	if( !GnLogger::UseUserSystemLog() )
		GnAssert(false);

#if defined(GNDEBUG)
	SetUseLogger( DEBUGEXT );	
	if( GnLogger::GetUseFileLog() )
		SetOutputFile( DEBUGEXT, "GnEngineDebugLog", 30*1024*1024, 5 );
	else
		SetOutputDebug( DEBUGEXT );
#endif // defined(GNDEBUG)

	SetUseLogger( ERRORTEXT );
	SetUseLogger( WARINGTEXT );
	if( GnLogger::GetUseFileLog() )
	{
		SetOutputFile( ERRORTEXT, "GnEngineErrorLog", 30*1024*1024, 5 );		
		SetOutputFile( WARINGTEXT, "GnEngineWaringLog", 30*1024*1024, 5 );
	}
	else
	{
		SetOutputDebug( ERRORTEXT );
		SetOutputDebug( WARINGTEXT );
	}
#endif // defined(GNDEBUG) || defined(GNLOG)
}

void GnLogger::Write(const gtchar* logName, int logLevel, const gtchar* format, va_list& kArgs)
{
	gtchar message[gMaxMessageLength] = {0,};
	gsize messageLength = GnTvssprintf( message, sizeof(message), format, kArgs );
#if defined(GNDEBUG) || defined(GNLOG)
	if( messageLength > gMaxMessageLength - 3 )
	{
		GnOutputDebugString( GnText( "Overed LogBuffer" ) );
	}
#endif // defined(GNDEBUG) || defined(GNLOG)
	
	LineCheck(message, messageLength);
	std::vector<gtstring>::iterator iterList = mUseLoggerList.begin();
	while ( iterList != mUseLoggerList.end() )
	{
		if( (*iterList) == logName )
		{
			mWriteLog( logName, message, logLevel );
			break;
		}
		++iterList;
	}
}

void GnLogger::WriteOutputDebug(gtchar* format, ...)
{
	gtchar message[gMaxMessageLength] = {0,};
	va_list kArgs;
	va_start( kArgs, format );
	gsize messageLength = GnTvssprintf( message, sizeof(message), format, kArgs );
	va_end( kArgs );
	
#if defined(GNDEBUG) || defined(GNLOG)
	if( messageLength >= gMaxMessageLength - 3 )
	{
		GnOutputDebugString( GnText( "Overed LogBuffer" ) );
	}
#endif // defined(GNDEBUG) || defined(GNLOG)

	LineCheck(message, messageLength);
	GnOutputDebugString(message);
}